#pragma  once
#include "base/core/point2.h"
#include "base/core/point3.h"
#include "LogicService.h"
#include "Map.h"
#include "Grid.h"
#include "Activity/GActivity.h"
#include "Common/CharacterDefine.h"


class Creature;
class Player;
class Monster;
class Npc;
class Drop;
class CRebot;
class Scene
{
	typedef std::unordered_map<CharIDType, Creature*> mapScenesNoPlayerCreatures;
	typedef std::unordered_map<CharIDType, Player*> mapScenesPlayers;
	typedef std::list<CharIDType> CidLst;
	typedef std::list<Point2<uint32_t> > Point2Lst;
	typedef std::unordered_map<CharIDType, bool> CidLeaveMap;

	typedef std::vector<vector<Grid> >  MAPGRID;
	typedef std::vector<Grid>  VGRID;


protected:
	uint32_t m_mapId;
	uint32_t m_sceneId;
	int32_t m_mapType;
	int32_t m_mapSubType;
	mapScenesNoPlayerCreatures m_sceneNoPlayerCreatures;
	mapScenesPlayers m_scenePlayers;
	//MAP_UINT64_UINT32 m_sceneNotPlayerCreatureIds; 
	//MAP_UINT64_UINT32 m_scenePlayerIds;
	//Grid** m_pMapGrid;
	MAPGRID m_vMapGrid;
	
	CidLeaveMap m_leaveCidMap;  //离开列表
	bool m_updating;   //更新标记

	uint32_t m_gridmaxWidth;  //地图宽度格子数
	uint32_t m_gridmaxHight;  //地图长度格子数
	uint32_t m_curGridCount;  //当前地图格子数

	bool IsInDelMap(CharIDType Cid);
	template<typename T> T *GetCreature(CharIDType cid);
	VECTOR_Creature m_vecUpdate; //每次update需要更新的生物指针vector
	int32_t m_updateCount;		//当前更新的次数计数
	int32_t m_updateMax;		//m_vecUpdate 当前最大大小
public:
	virtual bool Init(uint32_t mapId, uint32_t sceneId);
	virtual bool UnInit();
	virtual bool Update(uint64_t tick);

	uint32_t GetMapId() const { return m_mapId; }
	uint32_t GetSceneId() const { return m_sceneId; }
	bool     CanDestory() const { return false; }
	bool     IsDynamic() const;
	bool     IsUnion() const;
	bool     IsUnionDungeon() const;
	Creature* GetCreature(CharIDType cid);
	Player* GetPlayer(CharIDType cid);
	Drop *GetDrop(CharIDType cid);
	Monster *GetMonster(CharIDType cid);
	Npc *GetNpc(CharIDType cid);

	CRebot *GetRebot(CharIDType cid);
	const mapScenesPlayers* GetAllPlayerInScene() { return &m_scenePlayers; }
	const mapScenesNoPlayerCreatures* GetAllNoPlayerInScene() { return &m_sceneNoPlayerCreatures; }
	void GetAllMonsterInScene(SET_UINT64 &setSceneMonsters);
	void GetAllCreatureInScene(std::vector<Creature*>& vec);
	void GetAllDropInScene(SET_UINT64 &setDrop);
	Npc * GetNpcByCfgId(uint32_t npcCfgID);
	void GetAllFightNpc(SET_UINT64 &setFightNpc);
	Monster *GetMonsterByCfgId(uint32_t monsId);
	int32_t MonsNumByMasterCid(uint32_t monsId,CharIDType monsMasterCid);
	int32_t GetPlayerCount();

	virtual Grid* EnterScene(CharIDType Cid, Point3<float>& pos, Creature* pCreature, STransParam &transParam);
	virtual Grid* MoveInScene(CharIDType Cid, Grid *pGrid, Point3<float>& pos, bool & isSameGrid);
	virtual bool LeaveScene(CharIDType Cid, Grid *pGrid);
	virtual void RemoveCreature(CharIDType Cid);

	bool BroadCast2ClientInScene(uint32_t cmd, ProtoBufBase* buf); //废弃
	bool BroadCast2SysInScene(uint32_t cmd, ProtoBufBase* buf, uint32_t moudle = EMODULE_ID_SCENE);
	bool BroadCast2ClientInScene(uint32_t module, uint32_t cmd, ProtoBufBase* buf);
	bool BroadCast(SET_UINT64 &setChar, uint32_t module, uint32_t cmd, ProtoBufBase* buf);

	uint32_t GetGridLayer(uint32_t gridX, uint32_t gridZ, Point3<float>& srcPos, float flength);
	void FindCreatureInScene(CidLst& clist, Point3<float>& srcPos, float flength, uint32_t creatureCount = 0);
	void FindCreatureInBall(CidLst& clist, Point3<float>& srcPos, float flength, uint32_t creatureCount = 0);
	void FindCreatureInCircle(CidLst& clist, Point3<float>& srcPos, float flength, uint32_t creatureCount = 0);
	void FindCreatureInSector(CidLst& clist, Point3<float>& center, Point3<float>& dir, float angle, float sectorR, uint32_t creatureCount = 0);
	//srcPos是玩家位置，srcDir是玩家移动方向
	void FindCreatureInRect(CidLst& clist, Point3<float>& srcPos, Point3<float>& srcDir, float flength, float fwidth, uint32_t creatureCount = 0);
	void FindCreatureInRect(CidLst& clist, Point3<float>& center, Point3<float>& dir, Point3<float>& searchpos, float flength, float fwidth, uint32_t creatureCount = 0);
	void FindCreatueInNineGride(CidLst& clist, Point3<float>& srcPos);
	void FindCreatueInNineGride(Creature* pSrc, std::vector<Creature*>* clist, Point3<float>& srcPos);
	void FindSeeLstInNineGride(Creature* pSrc, std::vector<Creature*>* clist, Point3<float>& srcPos);
	void FindDoubleSeeLstInNineGride(Creature* pSrc, std::vector<Creature*>& clist, Point3<float>& srcPos);
	void AddRangeLstCids(CidLst& clist, Point3<float>& srcPos, Creature* pTarget, uint32_t creatureCount);

	void GridCreaturesWithBall(CidLst& clist, Point2<uint32_t>& gridpos, Point3<float>& srcPos, float flength, uint32_t creatureCount = 0);
	void GridCreaturesWithCircle(CidLst& clist, Point2<uint32_t>& gridpos, Point3<float>& srcPos, float flength, uint32_t creatureCount = 0);
	void GridCreaturesWithSector(CidLst& clist, Point3<float>& center, Point3<float>& vdir, Point2<uint32_t>& gridpos, float cosAngle, float sectorR, uint32_t creatureCount = 0);
	void GridCreaturesWithRect(CidLst& clist, Point2<uint32_t>& gridpos, Point3<float>& center, Point3<float>& dir, float flength, float fwidth, uint32_t creatureCount = 0);

	bool InBall(Point3<float>& from, Point3<float>& to, float flength);
	bool InCircle(Point3<float>& from, Point3<float>& to, float flength);
	bool InSector(Point3<float>& center, Point3<float>& vdir, Point3<float>& targetPos, float cosAngle, float sectorR);
	bool InRect(Point3<float>& position, Point3<float> &center, float length, float width, Point3<float>& dir);

	bool InArea(uint32_t nAreaId, Point3<float>& pos); //是否在区域范围
	void FindPointLstInRect(Point3<float>& center, VecPoint3 &vecPos, float fwidth, float fhigh, int32_t pointCnt);

	//获取A点到B点的等分点
	void GetSrcToDstDivisionPoints(Point3<float>& from, Point3<float>& to, VecPoint3& points, float division);
	//是否是技能有效区域 返回false表示有阻挡无法命中 true表示改技能可以命中 division等分点
	bool IsSkillEffectiveArea(Point3<float>& from, Point3<float>& to, float division = 10.f);

	//判断场景是否空人
	bool IsPlayerEmpty();

	//查找同场景同队伍的人
	void GetSameTeamPlayerIds(uint32_t teamId, LIST_INT64& clist);

	Scene();
	virtual ~Scene();

};
